from collections import defaultdict
from enum import Enum


class Trigger(Enum):
    Player = 1
    Target = 2
    Global = 3


class meta():
    priority = 1000
    forced = True

    def __call__(self, event, _status, game, ui):
        func = self.__class__.__dict__.get(f"step{event.step}")
        if func:
            func(self, event, _status, game, ui)
        else:
            event.finish()

    @classmethod
    def skill_type(cls):
        return cls.mro()[1].__name__

    @classmethod
    def trigger_type(cls):
        if hasattr(cls, "trigger"):
            return cls.trigger.name
        else:
            return ""

    @classmethod
    def get_name(cls):
        return cls.__name__


######################################################################################################################
################################        全局技能   ####################################################################
######################################################################################################################
class global_skill(meta):
    priority = 10000


class game_begin_hook(global_skill):
    trigger = Trigger.Global
    times = "game_begin"

    def step0(self, event, _status, game, ui):
        event.player.draw_cards(5, triggering=0)

    def step1(self, event, _status, game, ui):
        event.player.add_skill(0)

    def step2(self, event, _status, game, ui):
        event.player.change_coin(50)

######################################################################################################################
################################        英雄技能   ####################################################################
######################################################################################################################
class player_skill(meta):
    priority = 30000


######################################################################################################################
################################        卡牌技能   ####################################################################
######################################################################################################################
class card_skill(meta):
    priority = 20000


##########################移动类技能###################################################
class move1(card_skill):
    def step0(self, event, _status, game, ui):
        event.player.choose_field(1, to_self=False)

    def step1(self, event, _status, game, ui):
        event.player.move_to(event.child_result)

######################################################################################################################
################################        技能hook   ####################################################################
######################################################################################################################
skills_hook_map = defaultdict(list)

local_dict = locals().copy()
for k in local_dict:
    skill = local_dict[k]
    if hasattr(skill, "trigger") and hasattr(skill, "times"):
        if not isinstance(skill.times, tuple):
            skill.times = (skill.times,)
        for time in skill.times:
            skills_hook_map[time].append(skill)
for skills in skills_hook_map.values():
    key = lambda skill: skill.trigger.value
    skills.sort(key=key, reverse=True)
    key = lambda skill: skill.priority
    skills.sort(key=key)

player_skills = defaultdict(lambda: {0: [], 1: [], 2: []})
for k in local_dict:
    skill_class = local_dict[k]

    try:
        if issubclass(skill_class, player_skill):
            if not skill_class is player_skill:
                id, index, *_ = skill_class.get_name().split("_")
                player_skills[id][int(index)].append(skill_class)
    except:
        pass
